package com.sprouting.personal.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Dict;
import com.sprouting.personal.model.entity.PsPassword;
import com.sprouting.personal.model.vo.PsPasswordVo;
import com.sprouting.personal.service.DictService;
import com.sprouting.personal.service.PsPasswordService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 密码
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/11/11 15:20
 */
@RequestMapping("/cypher")
@RestController
public class PsPasswordController {

    @Autowired
    private PsPasswordService psPasswordService;
    @Autowired
    private DictService dictService;


    /**
     * 根据条件查询全部的密码
     * @param psPassword 查询条件
     * @return
     */
    @PostMapping("/getPasswordAll")
    public ResultJson getPasswordAll(PsPasswordVo psPassword){
        if (psPassword == null){
            psPassword = new PsPasswordVo();
        }
        psPassword.setUserId(StpUtil.getLoginIdAsString());
        return ResultJson.success(psPasswordService.getPasswordAll(psPassword));
    }

    /**
     * 获取密码类型
     * @return
     */
    @PostMapping("/getPsPasswordType")
    public ResultJson<List<Dict>> getPsPasswordType(){
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.PASSWORD_GROUP, StpUtil.getLoginIdAsString());
        return ResultJson.success(dictList);
    }

    /**
     * 逻辑删除密码
     * @param id 密码主键
     * @return
     */
    @PostMapping("/delPsPasswordById")
    public ResultJson delPsPasswordById(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }

        PsPassword password = psPasswordService.getPasswordById(id);
        // 密码比较重要，不进行物理删除
        EntityTool.buildDelBase(password, StpUtil.getLoginIdAsString());
        psPasswordService.updateById(password);
        return ResultJson.success();
    }

    /**
     * 更新密码
     * @param psPassword 密码信息
     * @return
     */
    @PostMapping("/updPsPassword")
    @ApiIdempotent
    public ResultJson<PsPassword> updPsPassword(@Validated(UpdGroup.class) PsPassword psPassword){
        String msg = checkPassword(psPassword);
        if (msg != null){
            return ResultJson.error(msg);
        }

        EntityTool.buildUpdBase(psPassword, StpUtil.getLoginIdAsString());
        psPasswordService.updateById(psPassword);
        return ResultJson.success(psPassword);
    }

    /**
     * 保存密码
     * @param psPassword 密码信息
     * @return
     */
    @PostMapping("/savePsPassword")
    @ApiIdempotent
    public ResultJson<PsPassword> savePsPassword(@Validated(AddGroup.class) PsPassword psPassword){
        String msg = checkPassword(psPassword);
        if (msg != null){
            return ResultJson.error(msg);
        }

        psPassword.setId(IdTool.getId());
        psPassword.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(psPassword, StpUtil.getLoginIdAsString());
        psPasswordService.save(psPassword);
        return ResultJson.success(psPassword);
    }

    /**
     * 生成随机密码
     * @param strLength 密码中字符串数量
     * @param numLength  数字数量
     * @param specialLength 特殊字符数量
     * @return
     */
    @PostMapping("/createPassword")
    public ResultJson createPassword(Integer strLength, Integer numLength, Integer specialLength){
        if (strLength == null){
            strLength = 0;
        }
        if (numLength == null){
            numLength = 0;
        }
        if (specialLength == null){
            specialLength = 0;
        }

        int num = strLength + numLength + specialLength;
        if (num == 0 || num < 0){
            // 采用默认策略生成密码
            strLength = 8;
            numLength = 2;
            specialLength = 2;
        }


        // 生成密码用的特殊字符
        ArrayList<String> specialList = CollUtil.newArrayList("!", "@", "#", "$", "%");
        ArrayList<String> numList = CollUtil.newArrayList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
        // 去掉大写的I,保留小写 i,去掉小写的l,保留大写的L,去掉大写的O,保存小写的o
        ArrayList<String> strList = CollUtil.newArrayList("A", "a", "B", "b", "C", "c", "D", "d", "E", "e", "F", "f", "G", "g", "H", "h", "i",
                "J", "j", "K", "k", "L", "M", "m", "N", "n", "o", "P", "p", "Q", "q", "R", "r", "S", "s", "T", "t", "U", "u", "V", "W", "w",
                "X", "x", "Y", "y", "Z", "z");

        List<String> randomList = new ArrayList<>();
        if (strLength > 0){
            List<String> list = RandomUtil.randomEles(strList, strLength);
            randomList.addAll(list);
        }
        if (numLength > 0){
            List<String> list = RandomUtil.randomEles(numList, numLength);
            randomList.addAll(list);
        }
        if (specialLength > 0){
            List<String> list = RandomUtil.randomEles(specialList, specialLength);
            randomList.addAll(list);
        }
        Collections.shuffle(randomList);
        String join = CollUtil.join(randomList, "");
        return ResultJson.success(join);
    }

    /**
     * 校验密码
     * @param psPassword 密码
     * @return 非null则是错误信息
     */
    public String checkPassword(PsPassword psPassword){
        PsPassword passwordDb = psPasswordService.getPasswordByName(psPassword.getId(), StpUtil.getLoginIdAsString(), psPassword.getName());
        if (passwordDb != null){
            return "存在重名的密码，请先检查";
        }
        if (CheckTool.checkNull(psPassword.getUserMemberFamilyId())){
            psPassword.setUserMemberFamilyId(Constant.DefaultValue.STRING);
        }

        return null;
    }
}
